<!--
 * @Description:
 * @Author: dh
 * @Date: 2021-08-19 17:18:39
 * @LastEditors: dh
 * @LastEditTime: 2025-09-09 14:35:11
-->
<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>History 模式</title>
	</head>

	<!-- 开启服务打开 -->

	<!-- 小知识：pushState 和 replaceState 都是 HTML5 的新 API，他们的作用很强大，可以做到改变浏览器地址却不刷新页面。这是实现改变地址栏却不刷新页面的重要方法。 -->

	<body>
		<div>
			<ul>
				<li><a href="/page1">page1</a></li>
				<li><a href="/page2">page2</a></li>
			</ul>
			<div id="route-view"></div>
		</div>
		<script type="text/javascript">
			window.addEventListener('DOMContentLoaded', Load);

			// TODO 需要注意的是调用 history.pushState() 或 history.replaceState() 不会触发 popstate 事件。
			// 只有在做出浏览器动作时，才会触发该事件，如用户点击浏览器的回退按钮（或者在Javascript代码中调用history.back()或者history.forward()方法）
			window.addEventListener('popstate', PopChange);

			var routeView = document.getElementById('route-view');

			function Load() {
				// 默认执行一次 popstate 的回调函数，匹配一次页面组件
				PopChange();
				// 遍历 a 标签节点数组，阻止默认事件，添加点击事件回调函数
				document.querySelectorAll('a[href]').forEach(aNode =>
					aNode.addEventListener('click', function (e) {
						e.preventDefault(); //阻止a标签的默认事件
						var href = aNode.getAttribute('href');
						//  手动修改浏览器的地址栏
						history.pushState(null, '', href);
						// 通过 history.pushState 手动修改地址栏，
						// TODO popstate 是监听不到地址栏的变化，所以此处需要手动执行回调函数 PopChange
						PopChange();
					})
				);
			}

			function PopChange() {
				console.log('location', location);
				switch (location.pathname) {
					case '/page1':
						routeView.innerHTML = 'page1';
						return;
					case '/page2':
						routeView.innerHTML = 'page2';
						return;
					default:
						routeView.innerHTML = 'page1';
						return;
				}
			}
		</script>
	</body>
</html>
